package com.per.demobeetlsql.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Map;

/**
 * @author Cheng
 * @date 2020/9/24 15:24
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

    private static DynamicDataSource instance;

    static Map<Object, Object> dynamicTargetDataSources;

    public static DynamicDataSource getInstance() {
        if (instance == null) {
            synchronized (DynamicDataSource.class) {
                if (instance == null) {
                    instance = new DynamicDataSource();
                }
            }
        }
        return instance;
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return DbContextHolder.getDataSourceKey();
    }

    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        super.setTargetDataSources(targetDataSources);
        dynamicTargetDataSources = targetDataSources;
    }

    /**
     * 创建数据源
     *
     * @param key        数据源名称
     * @param driveClass 数据源类型
     * @param url        数据源连接字符串
     * @param username   用户名
     * @param password   密码
     * @return 添加是否成功
     */
    public boolean createDataSource(String key, String driveClass, String url, String username, String password) {
        try {
            if (!linkDatasource(driveClass, url, username, password)) {
                return false;
            }
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setName(key);
            druidDataSource.setDriverClassName(driveClass);
            druidDataSource.setUrl(url);
            druidDataSource.setUsername(username);
            druidDataSource.setPassword(password);
            druidDataSource.setMaxWait(60000);
            druidDataSource.setFilters("stat");
            druidDataSource.init();
            Map<Object, Object> dynamicTargetDataSources2 = dynamicTargetDataSources;
            // 加入map
            dynamicTargetDataSources2.put(key, druidDataSource);
            // 将map赋值给父类的TargetDataSources
            this.setTargetDataSources(dynamicTargetDataSources2);
            // 将TargetDataSources中的连接信息放入resolvedDataSources管理
            super.afterPropertiesSet();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断数据库是否能连接
     *
     * @param driveClass 连接驱动
     * @param url        连接地址
     * @param username   用户名
     * @param password   密码
     * @return 连接是否成功
     */
    private boolean linkDatasource(String driveClass, String url, String username, String password) {
        Connection connection = null;
        try {
            // 排除连接不上的错误
            Class.forName(driveClass);
            //
            DriverManager.setLoginTimeout(1);
            // 相当于连接数据库
            connection = DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            return false;
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }
}
